'''
Author        zzx
Date          2023-03-20 17:02:46
LastEditTime  2023-03-22 15:55:50
LastEditors   zzx
Description   动态定时任务
'''

import uuid
from apscheduler.triggers.combining import AndTrigger
from app.extensions import apscheduler

# from app.extensions import apscheduler  # 直接导入单例对象操作也行


class APScheduler(object):
    """调度器控制方法"""

    def add_job(self, job_id, func, args, **kwargs):
        """
        添加任务
        :param args:  字典
        :param jobstore:  存储位置
        :param trigger:
                        data ->  run_date   datetime表达式
                        cron ->  second/minute/day_of_week
                        interval ->  seconds 延迟时间
                        next_run_time ->  datetime.datetime.now() + datetime.timedelta(seconds=12))
        :return:
        """
        job_def = dict(kwargs)
        job_def['id'] = job_id if job_id else str(uuid.uuid4())
        job_def['func'] = func
        job_def['kwargs'] = args
        job_def = self.fix_job_def(job_def)
        self.remove_job(job_id)  # 删除原job
        apscheduler.scheduler.add_job(**job_def)
        # apscheduler.shutdown()
        # apscheduler.start()

    def remove_job(self, job_id, jobstore=None):
        """删除任务"""
        if self.get_job(job_id):
            apscheduler.remove_job(job_id, jobstore=jobstore)

    def pause_job(self, job_id, jobstore=None):
        """暂停任务"""
        if self.get_job(job_id):
            apscheduler.pause_job(job_id, jobstore=jobstore)

    def update_job(self, job_id, data={}):
        """更新任务"""
        try:
            job = self.get_job(job_id=job_id)
            job.modify(**data)
            return True
        except Exception:
            return False

    def resume_job(self, job_id, jobstore=None):
        """恢复任务"""
        if self.get_job(job_id):
            apscheduler.resume_job(job_id, jobstore=jobstore)
            # apscheduler.shutdown()
            # apscheduler.start()

    def get_jobs(self, jobstore=None):
        """任务列表"""
        return apscheduler.get_jobs()

    def get_job(self, job_id):
        return apscheduler.get_job(job_id)

    def fix_job_def(self, job_def):
        """维修job工程"""
        if job_def.get('trigger') == 'date':
            job_def['next_run_time'] = job_def.get('next_run_time') or None
        elif job_def.get('trigger') == 'cron':
            job_def['month'] = job_def.get('month') or "*"
            job_def['week'] = job_def.get('week') or "*"
            job_def['day_of_week'] = job_def.get('day_of_week') or "*"
            job_def['day'] = job_def.get('day') or "*"
            job_def['hour'] = job_def.get('hour') or "*"
            job_def['minute'] = job_def.get('minute') or "*"
        elif job_def.get('trigger') == 'interval':
            job_def['seconds'] = job_def.get('seconds') or "*"
        else:
            if job_def.get("andTri"):
                job_def['trigger'] = AndTrigger([job_def.pop("andTri", None), ])
            # job_def['next_run_time'] = job_def.get('next_run_time') or None
        return job_def
